package com.carbeauty.entity;

import com.carbeauty.common.entity.BaseEntity;
import com.fasterxml.jackson.annotation.JsonFormat;
import jakarta.persistence.*;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Pattern;
import jakarta.validation.constraints.Size;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;

/**
 * 客户实体类
 * 
 * 客户管理功能:
 * - 基本信息管理
 * - 车辆信息管理
 * - 消费记录跟踪
 * - 会员等级管理
 * - 积分余额管理
 * 
 * @author CarBeauty Team
 */
@Entity
@Table(name = "cb_customer")
public class Customer extends BaseEntity {
    
    /**
     * 客户姓名
     */
    @NotBlank(message = "客户姓名不能为空")
    @Size(max = 50, message = "客户姓名长度不能超过50个字符")
    @Column(name = "name", nullable = false, length = 50)
    private String name;
    
    /**
     * 手机号码
     */
    @NotBlank(message = "手机号码不能为空")
    @Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号码格式不正确")
    @Column(name = "phone", nullable = false, length = 11)
    private String phone;
    
    /**
     * 会员卡号 - 自动生成
     */
    @Column(name = "card_no", unique = true, length = 20)
    private String cardNo;
    
    /**
     * 性别 (M-男, F-女, U-未知)
     */
    @Pattern(regexp = "^[MFU]$", message = "性别只能是M(男)、F(女)或U(未知)")
    @Column(name = "gender", length = 1)
    private String gender = "U";
    
    /**
     * 生日
     */
    @Column(name = "birthday")
    @JsonFormat(pattern = "yyyy-MM-dd")
    private LocalDate birthday;
    
    /**
     * 地址
     */
    @Size(max = 200, message = "地址长度不能超过200个字符")
    @Column(name = "address", length = 200)
    private String address;
    
    /**
     * 车牌号
     */
    @Size(max = 20, message = "车牌号长度不能超过20个字符")
    @Column(name = "car_number", length = 20)
    private String carNumber;
    
    /**
     * 车辆品牌
     */
    @Size(max = 50, message = "车辆品牌长度不能超过50个字符")
    @Column(name = "car_brand", length = 50)
    private String carBrand;
    
    /**
     * 车辆型号
     */
    @Size(max = 50, message = "车辆型号长度不能超过50个字符")
    @Column(name = "car_model", length = 50)
    private String carModel;
    
    /**
     * 车辆颜色
     */
    @Size(max = 20, message = "车辆颜色长度不能超过20个字符")
    @Column(name = "car_color", length = 20)
    private String carColor;
    
    /**
     * 账户余额
     */
    @Column(name = "balance", precision = 10, scale = 2)
    private BigDecimal balance = BigDecimal.ZERO;
    
    /**
     * 积分
     */
    @Column(name = "points")
    private Integer points = 0;
    
    /**
     * 会员等级
     */
    @Column(name = "member_level", length = 20)
    private String memberLevel = "普通会员";
    
    /**
     * 累计消费金额
     */
    @Column(name = "total_consumption", precision = 10, scale = 2)
    private BigDecimal totalConsumption = BigDecimal.ZERO;
    
    /**
     * 消费次数
     */
    @Column(name = "consumption_count")
    private Integer consumptionCount = 0;
    
    /**
     * 最后消费时间
     */
    @Column(name = "last_consumption_time")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime lastConsumptionTime;
    
    /**
     * 客户来源
     */
    @Size(max = 50, message = "客户来源长度不能超过50个字符")
    @Column(name = "source", length = 50)
    private String source;
    
    /**
     * 推荐人
     */
    @Size(max = 50, message = "推荐人长度不能超过50个字符")
    @Column(name = "referrer", length = 50)
    private String referrer;
    
    // ==================== 构造方法 ====================
    
    public Customer() {
        super();
    }
    
    public Customer(String name, String phone) {
        super();
        this.name = name;
        this.phone = phone;
        this.generateCardNo();
    }
    
    // ==================== Getter/Setter ====================
    
    public String getName() {
        return name;
    }
    
    public void setName(String name) {
        this.name = name;
    }
    
    public String getPhone() {
        return phone;
    }
    
    public void setPhone(String phone) {
        this.phone = phone;
    }
    
    public String getCardNo() {
        return cardNo;
    }
    
    public void setCardNo(String cardNo) {
        this.cardNo = cardNo;
    }
    
    public String getGender() {
        return gender;
    }
    
    public void setGender(String gender) {
        this.gender = gender;
    }
    
    public LocalDate getBirthday() {
        return birthday;
    }
    
    public void setBirthday(LocalDate birthday) {
        this.birthday = birthday;
    }
    
    public String getAddress() {
        return address;
    }
    
    public void setAddress(String address) {
        this.address = address;
    }
    
    public String getCarNumber() {
        return carNumber;
    }
    
    public void setCarNumber(String carNumber) {
        this.carNumber = carNumber;
    }
    
    public String getCarBrand() {
        return carBrand;
    }
    
    public void setCarBrand(String carBrand) {
        this.carBrand = carBrand;
    }
    
    public String getCarModel() {
        return carModel;
    }
    
    public void setCarModel(String carModel) {
        this.carModel = carModel;
    }
    
    public String getCarColor() {
        return carColor;
    }
    
    public void setCarColor(String carColor) {
        this.carColor = carColor;
    }
    
    public BigDecimal getBalance() {
        return balance;
    }
    
    public void setBalance(BigDecimal balance) {
        this.balance = balance;
    }
    
    public Integer getPoints() {
        return points;
    }
    
    public void setPoints(Integer points) {
        this.points = points;
    }
    
    public String getMemberLevel() {
        return memberLevel;
    }
    
    public void setMemberLevel(String memberLevel) {
        this.memberLevel = memberLevel;
    }
    
    public BigDecimal getTotalConsumption() {
        return totalConsumption;
    }
    
    public void setTotalConsumption(BigDecimal totalConsumption) {
        this.totalConsumption = totalConsumption;
    }
    
    public Integer getConsumptionCount() {
        return consumptionCount;
    }
    
    public void setConsumptionCount(Integer consumptionCount) {
        this.consumptionCount = consumptionCount;
    }
    
    public LocalDateTime getLastConsumptionTime() {
        return lastConsumptionTime;
    }
    
    public void setLastConsumptionTime(LocalDateTime lastConsumptionTime) {
        this.lastConsumptionTime = lastConsumptionTime;
    }
    
    public String getSource() {
        return source;
    }
    
    public void setSource(String source) {
        this.source = source;
    }
    
    public String getReferrer() {
        return referrer;
    }
    
    public void setReferrer(String referrer) {
        this.referrer = referrer;
    }
    
    // ==================== 业务方法 ====================
    
    /**
     * 生成会员卡号
     */
    public void generateCardNo() {
        if (this.cardNo == null || this.cardNo.isEmpty()) {
            // 格式: CB + 年月日 + 4位随机数
            String date = java.time.LocalDate.now().format(java.time.format.DateTimeFormatter.ofPattern("yyyyMMdd"));
            String random = String.format("%04d", (int)(Math.random() * 10000));
            this.cardNo = "CB" + date + random;
        }
    }
    
    /**
     * 增加余额
     */
    public void addBalance(BigDecimal amount) {
        if (amount != null && amount.compareTo(BigDecimal.ZERO) > 0) {
            this.balance = this.balance.add(amount);
        }
    }
    
    /**
     * 扣减余额
     */
    public boolean deductBalance(BigDecimal amount) {
        if (amount != null && amount.compareTo(BigDecimal.ZERO) > 0 
            && this.balance.compareTo(amount) >= 0) {
            this.balance = this.balance.subtract(amount);
            return true;
        }
        return false;
    }
    
    /**
     * 增加积分
     */
    public void addPoints(Integer points) {
        if (points != null && points > 0) {
            this.points += points;
        }
    }
    
    /**
     * 扣减积分
     */
    public boolean deductPoints(Integer points) {
        if (points != null && points > 0 && this.points >= points) {
            this.points -= points;
            return true;
        }
        return false;
    }
    
    /**
     * 更新消费信息
     */
    public void updateConsumption(BigDecimal amount) {
        if (amount != null && amount.compareTo(BigDecimal.ZERO) > 0) {
            this.totalConsumption = this.totalConsumption.add(amount);
            this.consumptionCount++;
            this.lastConsumptionTime = LocalDateTime.now();
            
            // 根据消费金额自动升级会员等级
            updateMemberLevel();
        }
    }
    
    /**
     * 根据累计消费金额更新会员等级
     */
    private void updateMemberLevel() {
        if (this.totalConsumption.compareTo(new BigDecimal("10000")) >= 0) {
            this.memberLevel = "钻石会员";
        } else if (this.totalConsumption.compareTo(new BigDecimal("5000")) >= 0) {
            this.memberLevel = "黄金会员";
        } else if (this.totalConsumption.compareTo(new BigDecimal("2000")) >= 0) {
            this.memberLevel = "银卡会员";
        } else if (this.totalConsumption.compareTo(new BigDecimal("500")) >= 0) {
            this.memberLevel = "铜卡会员";
        } else {
            this.memberLevel = "普通会员";
        }
    }
    
    /**
     * 获取会员折扣率
     */
    public BigDecimal getMemberDiscount() {
        return switch (this.memberLevel) {
            case "钻石会员" -> new BigDecimal("0.85");
            case "黄金会员" -> new BigDecimal("0.88");
            case "银卡会员" -> new BigDecimal("0.92");
            case "铜卡会员" -> new BigDecimal("0.95");
            default -> new BigDecimal("1.00");
        };
    }
}
